package com.sheep.jucdemo.part5.part5_2;

import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * CopyOnWriteArrayList的使用场景
 * <p>
 * commonBean
 * <p>
 * 于 2021-06-27 12:08:27 发布
 * <p>
 * 773
 * 收藏
 * 分类专栏： Java
 * 版权
 * <p>
 * Java
 * 专栏收录该内容
 * 32 篇文章0 订阅
 * 订阅专栏
 * 1.适用于数据量不大的场景，不适用于数据量大的场景。由于写操作的时候，需要拷贝数组，会消耗内存，如果原数组的内容比较多的情况下，可能导致young gc或者full gc
 * 2.适用于读多写少的场景，不适用于实时读的场景。
 * <p>
 * CopyOnWriteArrayList能保证写操作的线程安全，也能保证数据的最终一致性，但是无法保证数据的实时一致性。
 * <p>
 * CopyOnWriteArrayList在写操作中，使用了ReentrantLock锁以保证线程安全，并替换原array属性；
 * 但是读的时候直接读取array，可能会发生在写操作替换array前后。这就会导致读到旧数据，引发不一致。
 * <p>
 * 1、如果写操作未完成，那么直接读取原数组的数据；
 * 2、如果写操作完成，但是引用还未指向新数组，那么也是读取原数组数据；
 * 3、如果写操作完成，并且引用已经指向了新的数组，那么直接从新数组中读取数据。
 * ————————————————
 * 版权声明：本文为CSDN博主「commonBean」的原创文章，遵循CC 4.0 BY-SA版权协议，转载请附上原文出处链接及本声明。
 * 原文链接：https://blog.csdn.net/u011357213/article/details/118270926
 *
 * @Date 2022/4/18 22:06
 * @Created by sheep
 */
public class Test5_2_6 {

    private static volatile CopyOnWriteArrayList<String> arrayList = new CopyOnWriteArrayList<>();

    public static void main(String[] args) throws InterruptedException {
        arrayList.add("hello");
        arrayList.add("alibaba");
        arrayList.add("welcome");
        arrayList.add("to");
        arrayList.add("hangzhou");

        Thread threadOne = new Thread(new Runnable() {
            @Override
            public void run() {
                // 修改list中下标为1的元素为baba
                arrayList.set(1, "baba");
                // 删除元素
                arrayList.remove(2);
                arrayList.remove(3);
            }
        });
        // 保证在修改线程启动前获取迭代器
        Iterator<String> iterator = arrayList.iterator();
        // 启动线程
        threadOne.start();
        // 等待子线程执行完毕
        threadOne.join();
        // 迭代元素
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}
